﻿using System;
using System.Collections;
using System.Collections.Generic;

using zijian666.Converts.Abstractions;
using zijian666.Converts.Convertor.Base;
using zijian666.Converts.Core;
using zijian666.Converts.Extensions;

namespace zijian666.Converts.Convertor;

/// <summary>
/// <seealso cref="Hashtable"/> 哈希表转换器
/// </summary>
/// <typeparam name="T">实现了 <seealso cref="IDictionary"/> 的类型</typeparam>
public class HashtableConvertor<T> : AllowNullConvertor<T>, IFrom<object, T?>, IFrom<Dictionary<string, object>, T?>
    where T : class, IDictionary
{

    /// <summary>
    /// 转换器有错误
    /// </summary>
    private readonly bool _error;
    /// <summary>
    /// 转换器默认构造函数
    /// </summary>
    public HashtableConvertor() => _error = OutputType.MatchType(typeof(Hashtable), typeof(IDictionary)) is not MacthedType.Equals and not MacthedType.Acceptable and not MacthedType.TryCreate;
    /// <inheritdoc />
    public ConvertResult<T?> From(IConvertContext context, object input)
    {
        if (_error)
        {
            return ExceptionHelper.InstantiationFail(TypeFriendlyName, context.Settings.CultureInfo, null);
        }

        var enumerator = new KeyValueEnumerator<object, object>(context, input);
        if (enumerator.NotEnumerator)
        {
            return context.ConvertFail(this, input);
        }
        var hashtable = OutputType.IsInterface ? (IDictionary)new Hashtable() : context.Settings.CreateInstance<T>();
        while (enumerator.MoveNext())
        {
            hashtable.Add(enumerator.OriginalKey, enumerator.OriginalValue);
        }
        return (T)(object)hashtable;
    }

    /// <inheritdoc />
    public ConvertResult<T?> From(IConvertContext context, Dictionary<string, object> input) => From(context, (object)input);
}
